package com.bmslz.monitor.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bmslz.monitor.base.util.StringUtils;
import com.bmslz.monitor.base.dto.AttValueSearchDto;
import com.bmslz.monitor.base.entity.Project;
import com.bmslz.monitor.base.entity.ProjectData;
import com.bmslz.monitor.mapper.ProjectDataMapper;
import com.bmslz.monitor.service.IAlarmModelRuleService;
import com.bmslz.monitor.service.IProjectAlarmService;
import com.bmslz.monitor.service.IProjectDataService;
import com.bmslz.monitor.service.IProjectService;
import com.bmslz.monitor.base.vo.ProjectAttValuesVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


/**
 * @Description: 元数据
 * @Author: bobo
 * @Date: 2025-08-04
 * @Version: V1.0
 */
@Service
public class ProjectDataServiceImpl extends ServiceImpl<ProjectDataMapper, ProjectData> implements IProjectDataService {
    @Autowired
    private IProjectAlarmService projectAlarmService;
    @Autowired
    private IProjectService projectService;
    @Autowired
    private IAlarmModelRuleService alarmModelRuleService;
    @Override
    public void handle(List<ProjectData> projectDataList, Project project) {
        //当前方案 单次探针数据批量新增
        //进阶方案 多次探针数据批量新增 性能更佳
        //究极方案 入mq消息队列 进行异步消费 再多线程批量新增
        //存储方案暂时考虑mysql无分表，因为是自用且数据量不大 不考虑时序库和大数据库选型，因为系统设计理念是“轻量”
        this.saveBatch(projectDataList);

        //告警监控，异步执行，避免阻塞流量入口
        projectAlarmService.handleAsync(projectDataList, project);
    }

    @Override
    public List<ProjectAttValuesVo> queryAttValueList(AttValueSearchDto dto) {
        String projectId = dto.getProjectId();
        String attKey = dto.getAttKey();
        List<String> times = dto.getTimes();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<ProjectAttValuesVo> res = new ArrayList<>();
        if (StringUtils.isEmpty(projectId)) {
            return res;
        }
        if (StringUtils.isEmpty(attKey)) {
            return res;
        }
        if (times.size() < 2) {
            return res;
        }

        LambdaQueryWrapper<ProjectData> eq = new LambdaQueryWrapper<ProjectData>()
                .eq(ProjectData::getProjectId, projectId).eq(ProjectData::getAttKey, attKey)
                .ge(ProjectData::getHeartTime, times.get(0)).le(ProjectData::getHeartTime, times.get(1))
                .orderByAsc(ProjectData::getHeartTime);
        List<ProjectData> list = baseMapper.selectList(eq);

        return list.stream().map(projectData -> {
            ProjectAttValuesVo projectAttValuesVo = new ProjectAttValuesVo();
            projectAttValuesVo.setX(formatter.format(projectData.getHeartTime()));
            projectAttValuesVo.setY(projectData.getAttValue());
            return projectAttValuesVo;
        }).collect(Collectors.toList());
    }

    @Override
    public Long total(Date startTime, Date endTime) {
        LambdaQueryWrapper<ProjectData> wrapper = new LambdaQueryWrapper<ProjectData>();
        if (startTime != null) {
            wrapper.ge(ProjectData::getCreateTime, startTime);
        }
        if (endTime != null) {
            wrapper.le(ProjectData::getCreateTime, endTime);
        }
        return this.count(wrapper);
    }
}
